package com.qkl.xiatang.app.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qkl.xiatang.app.dto.BusinessDTO;
import com.qkl.xiatang.app.dto.FeedQty;
import com.qkl.xiatang.app.dto.PageOutDTO;
import com.qkl.xiatang.app.dto.feed.*;
import com.qkl.xiatang.app.dto.log.JobLogInDTO;
import com.qkl.xiatang.app.dto.log.JobLogOutDTO;
import com.qkl.xiatang.app.dto.log.JobLogTitleDTO;
import com.qkl.xiatang.app.dto.log.JobLogVO;
import com.qkl.xiatang.app.dto.message.CancelZooMessageDTO;
import com.qkl.xiatang.app.dto.message.SendWeighMessageDTO;
import com.qkl.xiatang.app.dto.pond.PondGroupDTO;
import com.qkl.xiatang.app.dto.pond.QueryPondNamesOutDTO;
import com.qkl.xiatang.app.entity.feed.*;
import com.qkl.xiatang.app.entity.pond.PondEntity;
import com.qkl.xiatang.app.entity.user.AppUserInfo;
import com.qkl.xiatang.app.exception.BusinessException;
import com.qkl.xiatang.app.mapper.FeedAllocCheckMapper;
import com.qkl.xiatang.app.mapper.FeedAllocMapper;
import com.qkl.xiatang.app.mapper.FeedAllocQtyMapper;
import com.qkl.xiatang.app.mapper.ZooAllocDetaiMapper;
import com.qkl.xiatang.app.service.config.FeedAllocConfigService;
import com.qkl.xiatang.app.service.pond.PondTemplateBindService;
import com.qkl.xiatang.app.utils.*;
import com.qkl.xiatang.app.utils.appenum.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.util.*;

/**
 * 饲料、动保配料喂料服务
 */
@Service
@Slf4j
public class FeedAllocService {

    @Autowired
    private FeedAllocMapper feedAllocMapper;

    @Autowired
    private PondManagerService pondManagerService;

    @Autowired
    private ConfigService configService;

    @Autowired
    private ZooAllocDetaiMapper zooAllocDetaiMapper;

    @Autowired
    private MessageService messageService;

    @Autowired
    private FeedManagerService feedService;

    @Autowired
    private PrintService printService;

    @Autowired
    private FeedStockService feedStockService;

    @Autowired
    private UploadFileService uploadFileService;

    @Autowired
    private AbnormalService abnormalService;

    @Autowired
    private FeedAllocCheckMapper feedAllocCheckMapper;

    @Autowired
    private FeedAllocQtyMapper feedAllocQtyMapper;

    @Autowired
    private PondNamesService pondNamesService;

    @Autowired
    private FeedAllocConfigService feedAllocConfigService;

    @Autowired
    private PondTemplateBindService pondTemplateBindService;

    public boolean pondIsAlloc(Date allocDate,List<String> pondIdList ){
        Integer cnt = feedAllocMapper.pondIsAlloc(allocDate,pondIdList);
        return null != cnt && cnt > 0;
    }

    public void addFeedAllocList(String companyId,String templateId,Date allocDate,List<String> pondIdList){
        List<FeedAllocDTO> list = new ArrayList<>();
        for(String pondId : pondIdList){
            FeedAllocDTO dto = new FeedAllocDTO();
            dto.setId(AppUtils.genIdStr(dto));
            dto.setAllocDate(allocDate);
            dto.setCompanyId(companyId);
            dto.setPondId(pondId);
            dto.setTemplateId(templateId);
            list.add(dto);
        }
        feedAllocMapper.addFeedAlloc(list);
    }

    public void deleteFeedAllocDetail(String companyId,Date allocDate,List<String> pondIdList,List<String> taskIdList){
        feedAllocMapper.deleteFeedAllocDetail(companyId,allocDate,pondIdList,taskIdList);
    }
    public void deleteFeedAllocDetail(Date allocDate,List<String> pondIdList,List<String> taskIdList){
        this.deleteFeedAllocDetail(AppSessionUtils.getCompanyId(),allocDate,pondIdList,taskIdList);
    }

    public void deleteFeedAllocQty(String companyId,Date allocDate,List<String> pondIdList,List<String> taskIdList){
        feedAllocMapper.deleteFeedAllocQty(companyId,allocDate,pondIdList,taskIdList);
    }
    public void deleteFeedAllocQty(Date allocDate,List<String> pondIdList,List<String> taskIdList){
        this.deleteFeedAllocQty(AppSessionUtils.getCompanyId(),allocDate,pondIdList,taskIdList);
    }

    public List<DecrQtyDTO> queryDecrQty(String companyId,Date allocDate,List<String> pondIdList,List<String> taskIdList){
        return feedAllocMapper.queryDecrQty(companyId,allocDate,pondIdList,taskIdList);
    }
    public List<DecrQtyDTO> queryDecrQty(Date allocDate,List<String> pondIdList,List<String> taskIdList){
        return this.queryDecrQty(AppSessionUtils.getCompanyId(),allocDate,pondIdList,taskIdList);
    }

    private List<String> getFeedAllocPondIds(FeedAllocAddBaseDTO webdto){
        List<String> pondIdList = new ArrayList<>();
        List<String> pondIds = webdto.getPondIdList();
        if(ObjectUtils.isNotEmpty(pondIds)){
            pondIdList.addAll(pondIds);
        }
        if(ObjectUtils.isNotEmpty(webdto.getGroupIdList())) {
            List<String> pondIdsGroup = pondManagerService.queryPondIdByGroup(webdto.getGroupIdList());
            log.info("==========getFeedAllocPondIds pondIdsGroup={}",pondIdsGroup);
            if(ObjectUtils.isNotEmpty(pondIdsGroup)){
                pondIdList.addAll(pondIdsGroup);
            }
        }
        pondIdList = AppUtils.stringsDistinct(pondIdList);
        log.info("==========getFeedAllocPondIds pondIdList={}",pondIdList);
        return pondIdList;
    }

    /**
     * 查询存在喂料任务
     * @param webdto
     * @return
     */
    public BusinessDTO<Object>  queryExistsFeedTask(FeedAllocAddBaseDTO webdto){
        List<String> pondIdList = this.getFeedAllocPondIds(webdto);
        Date allocDate = AppUtils.yyyyMMddToDate(webdto.getTime());
        String templateId = webdto.getTemplateId();
        String companyId = AppSessionUtils.getCompanyId();
        List<Map<String,Object>> taskList = null;
        if(ObjectUtils.isNotEmpty(pondIdList)){
            taskList = feedAllocMapper.queryExistsFeedTask(companyId,templateId,allocDate,pondIdList);
        }
        if(null == taskList){
            taskList = new ArrayList<>();
        }
        List<String> taskIdList = new ArrayList<>();
        Boolean isExistsTask = false;
        if(ObjectUtils.isNotEmpty(taskList)){
            isExistsTask = true;
            for (Map<String,Object> map : taskList){
                taskIdList.add( (String) map.get("taskId"));
            }
        }
        Map<String,Object> map = new HashMap<>();
        map.put("isExistsTask",isExistsTask);
        map.put("taskIdList",taskIdList);
        map.put("taskList",taskList);
        return BusinessDTO.sucessBusiness(map,"查询存在喂料任务");
    }

    /**
     * 配饲料
     * @param webDTO
     * @return
     */
    @Transactional
    public BusinessDTO<Object>  addFeedAlloc(FeedAllocAddWebDTO webDTO){
        String templateId = webDTO.getTemplateId();
        List<FeedAllocConfig> configList = feedAllocConfigService.getConfigList(templateId);
        if(ObjectUtils.isEmpty(configList)){
            return BusinessDTO.failBusiness("早、中、晚餐信息未配置");
        }
        pondManagerService.deletePondGruopDetail(webDTO.getPondIdList(),PondGroupTypeEnum.FEED.getType());
        List<String> pondIdList = this.getFeedAllocPondIds(webDTO);
        log.info("==========addFeedAlloc pondIdList={}",pondIdList);
        if(ObjectUtils.isEmpty(pondIdList)){
            throw new BusinessException("请选择塘口配料");
        }

        String companyId = AppSessionUtils.getCompanyId();
        List<String> taskIdList = webDTO.getTaskIdList();
        Date allocDate = AppUtils.yyyyMMddToDate(webDTO.getTime());
        AppUserInfo userInfo = AppSessionUtils.getSessionUser();
        String userId = AppSessionUtils.getUserId();

        AllocCheckInDTO params = new AllocCheckInDTO();
        params.setAllocDate(allocDate);
        params.setTemplateId(templateId);
        params.setPondIdList(pondIdList);
        params.setCompanyId(companyId);
        AllocCheckOutDTO checkOutDTO = feedAllocMapper.allocCheckTemplate(params);
        if( null != checkOutDTO){
            String templateName = feedAllocConfigService.getTemplateName(companyId,checkOutDTO.getTemplateId());
            throw new BusinessException("塘口[" + checkOutDTO.getPondName() + "] " + templateName + " 已喂料");
        }

        List<DecrQtyDTO> decrQtyDTOS = this.queryDecrQty(allocDate,pondIdList,taskIdList);
        if(ObjectUtils.isNotEmpty(decrQtyDTOS)){
            this.feedStock(userId,true,decrQtyDTOS);
        }
        this.deleteFeedAllocQty(allocDate,pondIdList,taskIdList);
        this.deleteFeedAllocDetail(allocDate,pondIdList,taskIdList);
        List<FeedQty>  qtyList = AppUtils.sumFeedQty(webDTO.getFeedDTOList());
        BusinessDTO<Object> businessDTO = this.isFeedStock(qtyList);
        if(!businessDTO.isSucess()){
            throw new BusinessException(businessDTO.getMessage());
        }
        boolean existsAllocFeed = messageService.existsAllocFeed(companyId,templateId,allocDate);

        List<FeedAllocDetailDTO> detailDTOS = new ArrayList<>();
        List<FeedAllocQtyDTO> feedAllocQtyList = new ArrayList<>();
        for(String pondId : pondIdList){
            FeedAllocAddWebDTO.AddDTO addDTO = FeedAllocAddWebDTO.AddDTO.newDTO(userInfo,companyId,templateId,pondId,allocDate);
            detailDTOS.addAll(webDTO.toDetailList(addDTO,configList,feedAllocQtyList));
        }
        Date createTime = new Date();
        this.addFeedAllocList(companyId,templateId,allocDate,pondIdList);
        feedAllocMapper.addFeedAllocDetail(detailDTOS);
        feedAllocMapper.addFeedAllocQty(feedAllocQtyList);
        if(ObjectUtils.isNotEmpty(taskIdList)) {
            int delCount = feedAllocQtyMapper.delete(new QueryWrapper<FeedAllocQtyEntity>()
                                                        .in("detail_id", taskIdList)
                                                        .ge("create_time", createTime));
            log.info("===addFeedAlloc.delete feedAllocQty delCount={}",delCount);
        }
        decrQtyDTOS = this.queryDecrQty(allocDate,pondIdList,null);
        this.feedStock(userId,false,decrQtyDTOS);

        SendWeighMessageDTO messageDTO = SendWeighMessageDTO.create(companyId,userInfo.getName(),allocDate,pondIdList,MessageTypeEnum.WEIGH_FEED,webDTO.getFeedIds());
        messageDTO.setTemplateId(templateId);
        messageService.sendWeighMessage(messageDTO);
        if( !existsAllocFeed){
            messageService.sendNotAllocFeedMessage(companyId,templateId,allocDate);
        }
        pondTemplateBindService.pondTemplateBindAsynch(companyId,templateId,pondIdList);
        return BusinessDTO.sucessBusiness(new HashMap<>(),"配饲料");
    }

    /**
     * 添加配料
     * @return
     */
    @Deprecated
    @Transactional
    public BusinessDTO<Object>  addFeedAlloc(FeedAllocAddDTO webdto){
        List<FeedAllocConfig>  configList = configService.getFeedAllocConfigList();
        if(ObjectUtils.isEmpty(configList)){
            return BusinessDTO.failBusiness("早、中、晚餐信息未配置");
        }
        String templateId = configList.get(0).getTemplateId();
        pondManagerService.deletePondGruopDetail(webdto.getPondIdList(),PondGroupTypeEnum.FEED.getType());
        List<String> pondIdList = this.getFeedAllocPondIds(webdto);
        log.info("==========addFeedAlloc pondIdList={}",pondIdList);
        if(ObjectUtils.isEmpty(pondIdList)){
            throw new BusinessException("请选择塘口配料");
        }
        String companyId = AppSessionUtils.getCompanyId();
        List<String> taskIdList = webdto.getTaskIdList();
        Date allocDate = AppUtils.yyyyMMddToDate(webdto.getTime());
        boolean existsAllocFeed = messageService.existsAllocFeed(companyId,templateId,allocDate);

        String userId = AppSessionUtils.getUserId();
        String userName = AppSessionUtils.getUserName();
        List<DecrQtyDTO> decrQtyDTOS = this.queryDecrQty(allocDate,pondIdList,taskIdList);
        if(ObjectUtils.isNotEmpty(decrQtyDTOS)){
            this.feedStock(userId,true,decrQtyDTOS);
        }
        this.deleteFeedAllocQty(allocDate,pondIdList,taskIdList);
        this.deleteFeedAllocDetail(allocDate,pondIdList,taskIdList);
        List<FeedAllocDetailDTO> detailDTOS = new ArrayList<>();
        List<FeedAllocQtyDTO> feedAllocQtyList = new ArrayList<>();
        for(String pondId : pondIdList){
            int checkSeparTime = configService.getCheckFeedTime(pondId);
            detailDTOS.addAll(webdto.toDetailList(userId,userName,pondId,companyId,allocDate,configList,checkSeparTime,feedAllocQtyList));
        }
        List<FeedQty>  qtyList = AppUtils.sumFeedQty(detailDTOS);
        BusinessDTO<Object> businessDTO = this.isFeedStock(qtyList);
        if(!businessDTO.isSucess()){
            throw new BusinessException(businessDTO.getMessage());
        }
        Date createTime = new Date();
        this.addFeedAllocList(companyId,templateId,allocDate,pondIdList);
        feedAllocMapper.addFeedAllocDetail(detailDTOS);
        feedAllocMapper.addFeedAllocQty(feedAllocQtyList);
        if(ObjectUtils.isNotEmpty(taskIdList)) {
            int delCount = feedAllocQtyMapper.delete(new QueryWrapper<FeedAllocQtyEntity>().in("detail_id", taskIdList).ge("create_time", createTime));
            log.info("===addFeedAlloc.delete feedAllocQty delCount={}",delCount);
        }
        decrQtyDTOS = this.queryDecrQty(allocDate,pondIdList,null);
        this.feedStock(userId,false,decrQtyDTOS);

        SendWeighMessageDTO messageDTO = SendWeighMessageDTO.create(companyId,userName,allocDate,pondIdList,MessageTypeEnum.WEIGH_FEED,webdto.getFeedIds());
        messageDTO.setTemplateId(templateId);
        messageService.sendWeighMessage(messageDTO);

       if( !existsAllocFeed){
           messageService.sendNotAllocFeedMessage(companyId,templateId,allocDate);
       }
        pondTemplateBindService.pondTemplateBindAsynch(companyId,templateId,pondIdList);
       return BusinessDTO.sucessBusiness(new HashMap<>(),"添加配料");
    }


    /**
     * 添加动保配料
     * @return
     */
    @Transactional
    public BusinessDTO<Object>  addZooAlloc(ZooAllocAddDTO webdto){
        ZooAllocAddDTO.ZooFeedDTO zooFeedDTO = webdto.toZooFeedDTO();
        List<String> feedIdList = zooFeedDTO.getFeedIdList();
        if(ObjectUtils.isEmpty(feedIdList)){
            return BusinessDTO.failBusiness("请选择动保类型");
        }

        String companyId = AppSessionUtils.getCompanyId();
        List<String> pondIdList = new ArrayList<>();
        List<String> pondDefineGroup = webdto.getPondIdList();
        pondManagerService.deletePondGruopDetail(pondDefineGroup,PondGroupTypeEnum.ZOO.getType());
        if(ObjectUtils.isNotEmpty(pondDefineGroup)){
            pondIdList.addAll(pondDefineGroup);
        }
        List<PondGroupDTO> pondGroupDTOS = null;
        if(ObjectUtils.isNotEmpty(webdto.getGroupIdList())) {
            pondGroupDTOS = pondManagerService.queryPondIdByGroup(companyId, webdto.getGroupIdList());
            for (PondGroupDTO groupDTO : pondGroupDTOS) {
                pondIdList.add(groupDTO.getPondId());
            }
        }
        pondIdList = AppUtils.stringsDistinct(pondIdList);
        if(ObjectUtils.isEmpty(pondIdList)){
            throw new BusinessException("请选择塘口");
        }

        Date allocDate = AppUtils.yyyyMMddToDate(webdto.getTime());
        String userId = AppSessionUtils.getUserId();
        String userName = AppSessionUtils.getUserName();
        List<DecrQtyDTO> decrQtyDTOS = feedAllocMapper.queryZooDecrQty(allocDate,feedIdList,pondIdList);
        if(ObjectUtils.isNotEmpty(decrQtyDTOS)){
            this.feedStock(userId,true,decrQtyDTOS);
            feedAllocMapper.deleteZooAllocDetail(allocDate,feedIdList,pondIdList);
        }
        List<ZooAllocDetailDTO> list = new ArrayList<>();
        if(ObjectUtils.isNotEmpty(pondGroupDTOS)) {
             list.addAll(webdto.toDetailByGroup(userId, userName,companyId, allocDate, pondGroupDTOS));
        }
        if(ObjectUtils.isNotEmpty(pondDefineGroup)){
            list.addAll(webdto.toDetailByPondIds(userId, userName,companyId, allocDate, pondDefineGroup));
        }
        List<FeedQty>  qtyList = AppUtils.sumFeedQty(list);
        BusinessDTO<Object> businessDTO = this.isFeedStock(qtyList);
        if(!businessDTO.isSucess()){
            throw new BusinessException(businessDTO.getMessage());
        }
        feedAllocMapper.addZooAllocDetail(list);
        decrQtyDTOS = feedAllocMapper.queryZooDecrQty(allocDate,feedIdList,pondIdList);
        this.feedStock(userId,false,decrQtyDTOS);


        SendWeighMessageDTO messageDTO = SendWeighMessageDTO.create(companyId,userName,allocDate,pondIdList,MessageTypeEnum.WEIGH_ZOO,feedIdList);
        messageService.sendWeighMessage(messageDTO);

        return BusinessDTO.sucessBusiness(new HashMap<>(),"添加动保配料");
    }

    /**
     * 查询喂料任务
     * @param pondId
     * @param allocDate
     * @return
     */
    public List<QueryFeedTaskDTO>  queryFeedTask(String pondId, Date allocDate){
        return feedAllocMapper.queryFeedTask(pondId,allocDate);
    }

    public BusinessDTO<Object> queryFeedTask(String pondId){
        PondEntity pond = pondManagerService.queryPondById(pondId);
        if(null == pond){
            return BusinessDTO.failBusiness("塘口不存在");
        }
        if(!pond.isUserCompany()){
            return BusinessDTO.failBusiness("非公司塘口");
        }
        Date allocDate = AppUtils.todayYyyyMMdd();
        List<QueryFeedTaskDTO> taskList = this.queryFeedTask(pondId,allocDate);
        if(ObjectUtils.isEmpty(taskList)){
            taskList = new ArrayList<>();
        }else {
            for (QueryFeedTaskDTO task: taskList){
                if(null == task.getQty()){
                    task.setQty(0.0);
                }
                if(ObjectUtils.isNotEmpty(task.getFeedList())){
                    task.setFeedImage(task.getFeedList().get(0).getFeedImage());
                    //task.setFeedName(task.getFeedList().get(0).getFeedName());
                }
            }
        }
        log.info("查询喂料任务 ====queryFeedTask taskList={}",taskList);
        Map<String,Object> map = new HashMap<>();
        map.put("pondId",pondId);
        map.put("pondName",pond.getName());
        map.put("taskList",taskList);
        return BusinessDTO.sucessBusiness(map,"查询喂料任务");
    }

    /**
     * 完成喂料任务
     * @param taskId
     * @return
     */
    public BusinessDTO<Object> finishFeedTask(String taskId){
        FeedAllocDetailEntity detailEntity = feedAllocMapper.selectById(taskId);
        if(null == detailEntity){
            return BusinessDTO.failBusiness("任务不存在");
        }
        Integer taskStatus = detailEntity.getStatus();
        String companyId = detailEntity.getCompanyId();
        if( !FeedAllocStatusEnum.isNotStatus(taskStatus)){
            return BusinessDTO.failBusiness("任务[" + FeedAllocStatusEnum.getStatusName(taskStatus) + "]");
        }
        Date now = new Date();
        if(now.compareTo(detailEntity.getStartTime()) < 0){
            return BusinessDTO.failBusiness("未到喂料时间");
        }
        /**
        if(now.compareTo(detailEntity.getEndTime()) > 0){
            return BusinessDTO.failBusiness("已过喂料时间");
        }
         **/
        Date feedTime = new Date();
        FeedAllocDetailEntity updEntity = new FeedAllocDetailEntity();
        updEntity.setId(detailEntity.getId());
        updEntity.setStatus(FeedAllocStatusEnum.OK.getStatus());
        updEntity.setFeedUserId(AppSessionUtils.getUserId());
        updEntity.setFeedUserName(AppSessionUtils.getUserName());
        updEntity.setFeedTime(feedTime);
        feedAllocMapper.updateById(updEntity);

        detailEntity.setFeedUserName(AppSessionUtils.getUserName());
        messageService.sendFeedMessageByFeed(detailEntity);
        messageService.sendCheckMessage(detailEntity,false);

        return BusinessDTO.sucessBusiness(new HashMap<>(),"完成喂料任务");
    }

    /**
     * 完成虾料称料任务
     * @param taskId
     * @return
     */
    public BusinessDTO<Object> finishWeighFeedTask(String taskId) {
        FeedAllocDetailEntity detailEntity = feedAllocMapper.selectById(taskId);
        if (null == detailEntity) {
            return BusinessDTO.failBusiness("任务不存在");
        }
        if(StringUtils.isEmpty(detailEntity.getWeighUserId())) {
            FeedAllocDetailEntity updEntity = new FeedAllocDetailEntity();
            updEntity.setId(detailEntity.getId());
            updEntity.setWeighUserId(AppSessionUtils.getUserId());
            updEntity.setWeighUserName(AppSessionUtils.getUserName());
            updEntity.setWeighTime(new Date());
            feedAllocMapper.updateById(updEntity);

            detailEntity.setWeighUserName(AppSessionUtils.getUserName());
            printService.printWeighFeed(detailEntity);

            //messageService.addMessage(AddMessageDTO.newDTO(MessageTypeEnum.FEED), detailEntity.getAllocDate(), feedAllocMapper.queryFeedIds(detailEntity.getId()));
            messageService.sendFeedMessageByWeigh(detailEntity);
        }else {
            log.info("虾料称料任务已完成,无须重复称料. =====WeighFeedTask taskId={}",taskId);
        }
        return BusinessDTO.sucessBusiness(new HashMap<>(),"完成虾料称料任务");
    }

    /**
     * 完成虾料称料当天任务
     * @param pondId
     * @param taskId
     * @return
     */
    public BusinessDTO<Object> finishWeighFeedTaskToday(String pondId,String taskId) {
        FeedAllocDetailEntity queryDetail = feedAllocMapper.selectById(taskId);
        if (null == queryDetail) {
            return BusinessDTO.failBusiness("任务不存在");
        }
        String feedAllocId = queryDetail.getFeedAllocId();
        String companyId = AppSessionUtils.getCompanyId();
        QueryWrapper queryWrapper = new QueryWrapper<FeedAllocDetailEntity>().eq("company_id",companyId).eq("feed_alloc_id",feedAllocId).eq("pond_id",pondId);
        List<FeedAllocDetailEntity> detailList = feedAllocMapper.selectList(queryWrapper);
        if(ObjectUtils.isNotEmpty(detailList)){
            Iterator<FeedAllocDetailEntity> it = detailList.iterator();
            while (it.hasNext()){
                FeedAllocDetailEntity detailEntity = it.next();
                if(StringUtils.isNotEmpty(detailEntity.getWeighUserId())){
                    it.remove();
                }
            }
        }
        if(ObjectUtils.isNotEmpty(detailList)){
            for (FeedAllocDetailEntity detail : detailList){
                FeedAllocDetailEntity updEntity = new FeedAllocDetailEntity();
                updEntity.setId(detail.getId());
                updEntity.setWeighUserId(AppSessionUtils.getUserId());
                updEntity.setWeighUserName(AppSessionUtils.getUserName());
                updEntity.setWeighTime(new Date());
                feedAllocMapper.updateById(updEntity);

                detail.setWeighUserName(AppSessionUtils.getUserName());
                //messageService.addMessage(AddMessageDTO.newDTO(MessageTypeEnum.FEED), detailEntity.getAllocDate(), feedAllocMapper.queryFeedIds(detailEntity.getId()));

                printService.printWeighFeed(detail);

                QueryWrapper wrapper = new QueryWrapper<FeedAllocDetailEntity>().eq("company_id",companyId).eq("alloc_date",detail.getAllocDate()).eq("status",0).eq("weigh_user_id","");
                if(ObjectUtils.isEmpty(feedAllocMapper.selectList(wrapper))){
                    //messageService.addMessage(AddMessageDTO.newDTO(MessageTypeEnum.FEED), detail.getAllocDate(), new ArrayList<>());
                }
            }

        }
        return BusinessDTO.sucessBusiness(new HashMap<>(),"完成虾料称料当天任务");
    }

    /**
     * 取消喂料任务
     * @param taskId
     * @return
     */
    @Transactional
    public BusinessDTO<Object> cancelFeedTask(String taskId){
        FeedAllocDetailEntity detailEntity = feedAllocMapper.selectById(taskId);
        if(null == detailEntity){
            return BusinessDTO.failBusiness("任务不存在");
        }
        Integer taskStatus = detailEntity.getStatus();
        if( !FeedAllocStatusEnum.isNotStatus(taskStatus)){
            return BusinessDTO.failBusiness("任务[" + FeedAllocStatusEnum.getStatusName(taskStatus) + "]");
        }
        FeedAllocDetailEntity updEntity = new FeedAllocDetailEntity();
        updEntity.setId(detailEntity.getId());
        updEntity.setStatus(FeedAllocStatusEnum.CANCEL.getStatus());
        updEntity.setFeedUserId(AppSessionUtils.getUserId());
        updEntity.setFeedUserName(AppSessionUtils.getUserName());
        updEntity.setFeedTime(new Date());
        //updEntity.setMemo(AppSessionUtils.getUserName() + " 取消任务");
        updEntity.setUpdateTime(new Date());
        feedAllocMapper.updateById(updEntity);
        this.feedStock(AppSessionUtils.getUserId(),false,detailEntity.getFeedId(),detailEntity.getQty());

        detailEntity.setFeedUserName(AppSessionUtils.getUserName());
        detailEntity.setStatus(FeedAllocStatusEnum.CANCEL.getStatus());
        messageService.sendCancelTaskMessage(detailEntity);

        return BusinessDTO.sucessBusiness(new HashMap<>(),"成功取消喂料任务");
    }

    /**
     * 查询动保任务
     * @param pondId
     * @param allocDate
     * @return
     */
    public List<Map<String,Object>>  queryZooTask(String pondId, Date allocDate){
        return feedAllocMapper.queryZooTask(pondId,allocDate);
    }

    public BusinessDTO<Object> queryZooTask(String pondId){
        PondEntity pond = pondManagerService.queryPondById(pondId);
        if(null == pond){
            return BusinessDTO.failBusiness("塘口不存在");
        }
        if(!pond.isUserCompany()){
            return BusinessDTO.failBusiness("非公司塘口");
        }
        Date allocDate = AppUtils.todayYyyyMMdd();
        List<Map<String,Object>> taskList = this.queryZooTask(pondId,allocDate);
        if(ObjectUtils.isEmpty(taskList)){
            taskList = new ArrayList<>();
        }
        Map<String,Object> map = new HashMap<>();
        map.put("zooTaskList",taskList);
        return BusinessDTO.sucessBusiness(map,"查询动保任务");
    }

    /**
     * 完成动保任务
     * @param taskId
     * @return
     */
    public BusinessDTO<Object> finishZooTask(String taskId){
        ZooAllocDetailEntity detailEntity = zooAllocDetaiMapper.selectById(taskId);
        if(null == detailEntity){
            return BusinessDTO.failBusiness("任务不存在");
        }
        Integer taskStatus = detailEntity.getStatus();
        if( !ZooAllocStatusEnum.isNotStatus(taskStatus)){
            return BusinessDTO.failBusiness("任务[" + ZooAllocStatusEnum.getStatusName(taskStatus) + "]");
        }
        ZooAllocDetailEntity updEntity = new ZooAllocDetailEntity();
        updEntity.setId(detailEntity.getId());
        updEntity.setStatus(ZooAllocStatusEnum.OK.getStatus());
        updEntity.setFeedUserId(AppSessionUtils.getUserId());
        updEntity.setFeedUserName(AppSessionUtils.getUserName());
        updEntity.setFeedTime(new Date());
        zooAllocDetaiMapper.updateById(updEntity);

        detailEntity.setFeedUserName(AppSessionUtils.getUserName());
        messageService.sendFeedMessageByFeed(detailEntity);;

        return BusinessDTO.sucessBusiness(new HashMap<>(),"完成动保任务");
    }

    /**
     * 完成动保称料任务
     * @param taskId
     * @return
     */
    public BusinessDTO<Object> finishWeighZooTask(String taskId){
        ZooAllocDetailEntity detailEntity = zooAllocDetaiMapper.selectById(taskId);
        if(null == detailEntity){
            return BusinessDTO.failBusiness("任务不存在");
        }
        if(StringUtils.isEmpty(detailEntity.getWeighUserId())) {
            ZooAllocDetailEntity updEntity = new ZooAllocDetailEntity();
            updEntity.setId(detailEntity.getId());
            updEntity.setWeighUserId(AppSessionUtils.getUserId());
            updEntity.setWeighUserName(AppSessionUtils.getUserName());
            updEntity.setWeighTime(new Date());
            zooAllocDetaiMapper.updateById(updEntity);

            printService.printWeighZoo(detailEntity.getPondId(), AppSessionUtils.getUserName(), detailEntity.getFeedId(), detailEntity.getQty());

            detailEntity.setWeighUserName(AppSessionUtils.getUserName());
            messageService.sendFeedMessageByWeigh(detailEntity);
        }else {
            log.info("动保称料任务已完成,无须重复称料. ====== WeighZooTask taskId={}",taskId);
        }
        return BusinessDTO.sucessBusiness(new HashMap<>(),"完成动保称料任务");
    }

    /**
     * 完成动保称料全部任务
     * @return
     */
    @Transactional
    public BusinessDTO<Object> finishWeighZooTaskAll(){
        FeedAllocQueryInDTO queryInDTO = new FeedAllocQueryInDTO();
        queryInDTO.setPageIndex(1);
        queryInDTO.setPageSize(1000);
        List<ZooWeighOutDTO> queryWeighList = this.queryZooAllocInfo(queryInDTO).getList();
        List<String> idList = new ArrayList<>();
        if(ObjectUtils.isNotEmpty(queryWeighList)){
            Map<String,List<String>> messageMap = new TreeMap<>();
            for(ZooWeighOutDTO weighTO : queryWeighList) {
                idList.add(weighTO.getTaskId());
                if( !messageMap.containsKey(weighTO.getAllocDate())){
                    messageMap.put(weighTO.getAllocDate(),new ArrayList<>());
                }
                messageMap.get(weighTO.getAllocDate()).add(weighTO.getFeedId());
            }

            FinishWeighZooDTO finishWeighZooDTO = new FinishWeighZooDTO();
            finishWeighZooDTO.setWeighUserId(AppSessionUtils.getUserId());
            finishWeighZooDTO.setWeighUserName(AppSessionUtils.getUserName());
            finishWeighZooDTO.setWeighTime(new Date());
            finishWeighZooDTO.setIdList(idList);
            feedAllocMapper.finishWeighZooTaskAll(finishWeighZooDTO);
            printService.printWeighZooList(AppSessionUtils.getUserName(),queryWeighList);

            //messageService.addMessageZoo(queryWeighList);
            messageService.sendFeedMessageByWeigh(AppSessionUtils.getCompanyId(),AppSessionUtils.getUserName(),messageMap);
        }
        return BusinessDTO.sucessBusiness(new HashMap<>(),"完成动保称料全部任务");
    }

    /**
     * 查询动保未完成任务
     * @param companyId
     * @return
     */
    List<Map<String,Object>> queryZooUnfinishTask(String companyId){
        return feedAllocMapper.queryZooUnfinishTask(companyId);
    }

    public BusinessDTO<Object> queryZooUnfinishTask(){
        String companyId = AppSessionUtils.getCompanyId();
        if(StringUtils.isEmpty(companyId)){
            return BusinessDTO.failBusiness("用户未登陆");
        }
        List<Map<String,Object>> zooTaskList = this.queryZooUnfinishTask(companyId);
        if(ObjectUtils.isEmpty(zooTaskList)){
            zooTaskList = new ArrayList<>();
        }
        Map<String,Object> map = new HashMap<>();
        map.put("zooTaskList",zooTaskList);
        return BusinessDTO.sucessBusiness(map,"动保未完成任务");
    }

    /**
     * 取消动保任务
     * @param taskGroupIdList
     * @return
     */
    @Transactional
    public BusinessDTO<Object> cancelZooTask(List<String> taskGroupIdList){
        List<CancelZooMessageDTO> cancelZooList = messageService.queryCancelZooMessage(taskGroupIdList);
        List<DecrQtyDTO> qtyList = feedAllocMapper.cancelZooAllocDetailQty(taskGroupIdList);
        this.feedStock(AppSessionUtils.getUserId(),true,qtyList);
       Integer count = feedAllocMapper.cancelZooAllocDetail(taskGroupIdList);
       if(null == count){
           count = 0;
       }
       messageService.sendCancelZooMessage(cancelZooList);
       Map<String,Object> map = new HashMap<>();
       map.put("cancelCount",count);
        return BusinessDTO.sucessBusiness(map,"取消动保任务");
    }

    /**
     * 取消动保称料任务
     * @param taskId
     * @return
     */
    public BusinessDTO<Object> cancelZooWeighTask(String taskId){
        ZooAllocDetailEntity zooEntity = zooAllocDetaiMapper.selectById(taskId);
        if(null == zooEntity){
            return BusinessDTO.failBusiness("任务不存在");
        }
        zooAllocDetaiMapper.deleteById(taskId);

        DecrQtyDTO qtyDTO = new DecrQtyDTO();
        qtyDTO.setQty(zooEntity.getQty());
        qtyDTO.setFeedId(zooEntity.getFeedId());
        this.feedStock(AppSessionUtils.getUserId(),true,qtyDTO);

        zooEntity.setFeedUserName(AppSessionUtils.getUserName());
        zooEntity.setStatus(FeedAllocStatusEnum.CANCEL.getStatus());
        messageService.sendCancelTaskMessage(zooEntity);
        return BusinessDTO.sucessBusiness(new HashMap<>(),"取消动保称料任务");
    }

    /**
     * 获取查料时间
     * @param pondId
     * @return
     */
    public BusinessDTO<Object> getCheckFeedTime(String pondId){
        Map<String,Object> map = new HashMap<>();
        FeedAllocDetailEntity task = this.findCheckFeedTask(pondId);
        int checkFeedTime = 0;
        Double qty = 0.0;
        String taskId = "";
        if(null != task ) {
            qty = task.getQty();
            taskId = task.getId();
            if(null != task.getFeedTime()) {
                checkFeedTime = Math.round((System.currentTimeMillis() - task.getFeedTime().getTime()) / 1000 / 60);
            }
        }
        Boolean isCheck = false;
        map.put("qty",qty);
        map.put("isCheck",isCheck);
        map.put("checkFeedTime",checkFeedTime);
        map.put("taskId",taskId);
        map.put("isTask",true);
        return BusinessDTO.sucessBusiness(map,"查料时间");

    }

    /**
     * 查料台
     * @param webdto
     * @return
     */
    public BusinessDTO<Object> checkFeedAlloc(FeedAllocCheckDTO webdto){
        log.info("=======.checkFeedAlloc webdto={}",webdto);
        String pondId = webdto.getPondId();
        String taskId = webdto.getTaskId();

        String abnorMemo = webdto.getAbnorMemo();
        if(StringUtils.isEmpty(abnorMemo)){
            abnorMemo = null;
        }
        List<String> abnorImageList = webdto.getAbnorImageList();
        Integer feedStatus = webdto.getFeedStatus();
        Integer shrimpStatus = webdto.getShrimpStatus();
        Integer loseCount = webdto.getLoseCount();
        String loseMemo = webdto.loseMemo();
        if(null != feedStatus && !FeedQtyStatusEnum.isStatus(feedStatus)){
            return BusinessDTO.failBusiness("非法参数,料量：" + feedStatus);
        }
        if(null != shrimpStatus && !ShrimpQtyStatusEnum.isStatus(shrimpStatus)){
            return BusinessDTO.failBusiness("非法参数,虾量：" + shrimpStatus);
        }
        if(null != loseCount && loseCount < 1){
            return BusinessDTO.failBusiness("非法参数,掉苗：" + loseCount);
        }

        if( StringUtils.isNotEmpty(abnorMemo) || ObjectUtils.isNotEmpty(abnorImageList)){
            return abnormalService.reportAbnormal(pondId,abnorMemo,abnorImageList);
        }
        if(null != loseCount){
            abnormalService.reportAbnormal(pondId,loseMemo,null);
        }

        FeedAllocDetailEntity task = null;
        if(StringUtils.isNotEmpty(taskId)){
            task = feedAllocMapper.selectById(taskId);
        }
        if(null == task){
            task= this.findCheckFeedTask(pondId);
        }
        if(StringUtils.isEmpty(pondId) && null != task){
            pondId = task.getPondId();
        }
        if(StringUtils.isEmpty(pondId)){
            return BusinessDTO.failBusiness("塘号不能为空");
        }

        Integer serialNo = null;
        String serialName = "";
        if(null != task){
            serialNo = task.getSerialNo();
            serialName = task.getName();
        }else {
            String templateId = pondTemplateBindService.queryTemplateId(pondId);
            List<FeedAllocConfig> configList = feedAllocConfigService.getConfigList(templateId,AppSessionUtils.getCompanyId());
            FeedAllocConfig config = FeedUtils.findFeedConfig(configList);
            if(null == config) {
                FeedAllocSerialEnum serialEnum = FeedUtils.getFeedAllocSerial();
                serialNo = serialEnum.getNo();
                serialName = serialEnum.getName();
            }else {
                serialNo = config.getSerialNo();
                serialName = config.getName();
            }
        }
        String statusMemo = ShrimpQtyStatusEnum.statusMemo(shrimpStatus,feedStatus);
        String checkTaskId = AppUtils.genIdStr();
        FeedAllocCheckEntity checkEntity = new FeedAllocCheckEntity();
        checkEntity.setId(checkTaskId);
        checkEntity.setCompanyId(AppSessionUtils.getCompanyId());
        checkEntity.setPondId(pondId);
        checkEntity.setAllocDate(AppUtils.todayYyyyMMdd());
        checkEntity.setFeedStatus(feedStatus);
        checkEntity.setShrimpStatus(shrimpStatus);
        checkEntity.setUserId(AppSessionUtils.getUserId());
        checkEntity.setUserName(AppSessionUtils.getUserName());
        checkEntity.setSerialNo(serialNo);
        checkEntity.setSerialName(serialName);
        checkEntity.setStatusName(statusMemo);
        checkEntity.setCreateTime(new Date());
        checkEntity.setLoseCount(loseCount);
        feedAllocCheckMapper.insert(checkEntity);

        Double qty = 0.0;
        if(null != task) {
            qty = task.getQty();
            FeedAllocDetailEntity updEntity = new FeedAllocDetailEntity();
            updEntity.setId(task.getId());
            updEntity.setFeedStatus(feedStatus);
            updEntity.setShrimpStatus(shrimpStatus);
            updEntity.setCheckUserId(AppSessionUtils.getUserId());
            updEntity.setCheckUserName(AppSessionUtils.getUserName());
            updEntity.setCheckTime(new Date());
            feedAllocMapper.updateById(updEntity);

            task.setCheckUserName(AppSessionUtils.getUserName());
            messageService.sendCheckMessage(task,true);
        }
        Map<String,Object> map = new HashMap<>();
        map.put("taskId",checkTaskId);
        map.put("name",serialName);
        map.put("qty",qty);
        map.put("allocDate",AppUtils.yyyyMMdd());
        return BusinessDTO.sucessBusiness(map,"查料台");
    }
    private FeedAllocDetailEntity findCheckFeedTask(String pondId){
        Date allocDate = AppUtils.todayYyyyMMdd();
        List<FeedAllocDetailEntity> taskList = feedAllocMapper.selectList(new QueryWrapper<FeedAllocDetailEntity>()
                                                                                .eq("pond_id",pondId)
                                                                                .eq("alloc_date",allocDate)
                                                                                .orderByAsc("start_time"));
        return FeedUtils.findCheckFeedTask(taskList);
    }

    /**
     * 工作日志查询
     * @param indto
     * @return
     */
    public BusinessDTO<JobLogOutDTO> queryJobLog(JobLogInDTO indto){
        String companyId = AppSessionUtils.getCompanyId();
        indto.setCompanyId(companyId);
        if(StringUtils.isAllEmpty(indto.getStartAllocDate(),indto.getEndAllocDate())){
            String today = AppUtils.toYyyyMMdd(new Date());
            indto.setStartAllocDate(today);
            indto.setEndAllocDate(today);
        }
        indto.checkParam();

        if(indto.isLogTypeZoo()){
            return this.queryZooJobLog(indto);
        }else if(indto.isLogTypeSale()){
            return this.querySaleJobLog(indto);
        }else if(indto.isLogTypeStockFeed() || indto.isLogTypeStockZoo()){
            return this.queryStockJobLog(indto);
        }else if(indto.isLogTypeVideo()){
            return uploadFileService.queryVideoJobLog(indto);
        }
        return this.queryJobLogFeed(indto);
    }

    /**
     * 工作日志下载
     * @param indto
     * @return
     */
    public DownloadJobLogDTO downloadJobLog(JobLogInDTO indto){
        indto.setPageIndex(1);
        indto.setPageSize(1000);
        String sheetName = "喂料日志";
        if(indto.isLogTypeZoo()){
            sheetName = "动保日志";
        }else if(indto.isLogTypeSale()){
            sheetName = "销售日志";
        }else if(indto.isLogTypeStockFeed()){
            sheetName = "饲料库存日志";
        }else if(indto.isLogTypeStockZoo()){
            sheetName = "动保库存日志";
        }
        JobLogOutDTO jogLog = this.queryJobLog(indto).getBusinessObject();

        DownloadJobLogDTO jobLogDTO = new DownloadJobLogDTO();
        jobLogDTO.setFilename(sheetName + ".xlsx");
        jobLogDTO.setWorkbook(ExcelUtils.createJobLog(sheetName,jogLog));
        return jobLogDTO;
    }

    /**
     * 喂料工作日志查询
     * @param indto
     * @return
     */
    public BusinessDTO<JobLogOutDTO> queryJobLogFeed(JobLogInDTO indto){
        List<JobLogTitleDTO> jobLogTitle = configService.queryJobLogTitle();
        Integer totalRow = feedAllocMapper.queryJobLogListTotal(indto);
        totalRow = null == totalRow? 0:totalRow;
        JobLogOutDTO outDTO = new JobLogOutDTO();
        outDTO.settingPage(indto,totalRow);
        if(totalRow > 0){
            List<JobLogVO> jobLogList = feedAllocMapper.queryJobLogList(indto);
            List<Map<String,Object>> dataList = new ArrayList<>();
            if(ObjectUtils.isNotEmpty(jobLogList)){
                for(JobLogVO logVO : jobLogList){
                    Map<String,Object> dataMap = logVO.toMap();
                    dataList.add(dataMap);
                }
            }
            outDTO.setList(dataList);
        }
        outDTO.setJobLogTitle(jobLogTitle);
        if(ObjectUtils.isEmpty(outDTO.getList())){
            outDTO.setList(new ArrayList());
        }
        return BusinessDTO.sucessBusiness(outDTO,"工作日志查询");
    }

    /**
     * 动保工作日志
     * @param indto
     * @return
     */
    public BusinessDTO<JobLogOutDTO> queryZooJobLog(JobLogInDTO indto){
        List<JobLogTitleDTO> jobLogTitle = new ArrayList<>();
        JobLogTitleDTO titleDTO = new JobLogTitleDTO();
        titleDTO.setKey("pondName");
        titleDTO.setName("塘号");
        jobLogTitle.add(titleDTO);

        titleDTO = new JobLogTitleDTO();
        titleDTO.setKey("allocDate");
        titleDTO.setName("配料员/日期");
        jobLogTitle.add(titleDTO);

        Integer totalRow = feedAllocMapper.queryZooJobLogListTotal(indto);
        totalRow = null == totalRow? 0:totalRow;
        JobLogOutDTO outDTO = new JobLogOutDTO();
        outDTO.settingPage(indto,totalRow);
        if(totalRow > 0){
            List<JobLogVO> jobLogList = feedAllocMapper.queryZooJobLogList(indto);
            List<Map<String,Object>> dataList = new ArrayList<>();
            if(ObjectUtils.isNotEmpty(jobLogList)){
                Map<String,String> logTitleMap = new HashMap<>();
                for(JobLogVO logVO : jobLogList){
                    Map<String,Object> dataMap = logVO.toZooMap(logTitleMap);
                    dataList.add(dataMap);
                }
                Set<Map.Entry<String, String>> titleKeySet = logTitleMap.entrySet();
                for(Map<String,Object> dataMap : dataList){
                    for(Map.Entry<String, String>  entry : titleKeySet){
                        if(!dataMap.containsKey(entry.getKey())){
                            dataMap.put(entry.getKey(),"");
                        }
                    }
                }

                for(Map.Entry<String, String>  entry : titleKeySet){
                    JobLogTitleDTO title = new JobLogTitleDTO();
                    title.setName(entry.getValue());
                    title.setKey(entry.getKey());
                    jobLogTitle.add(title);
                }
            }
            //补允页没有的表头
            List<Map<String,String>>  titleMapList = feedAllocMapper.queryZooJobLogTitle(indto);
            if(ObjectUtils.isNotEmpty(titleMapList)){
                for (Map<String,String> titleMap : titleMapList){
                    String key = titleMap.get("feedId");
                    String name = titleMap.get("feedName");
                    boolean isExistTitle = false;
                    for(JobLogTitleDTO title: jobLogTitle){
                        if(title.getKey().equals(key)){
                            isExistTitle = true;
                            break;
                        }
                    }
                    if(!isExistTitle){
                        JobLogTitleDTO title = new JobLogTitleDTO();
                        title.setName(name);
                        title.setKey(key);
                        jobLogTitle.add(title);
                    }
                }
            }

            outDTO.setList(dataList);
        }
        outDTO.setJobLogTitle(jobLogTitle);
        if(ObjectUtils.isEmpty(outDTO.getList())){
            outDTO.setList(new ArrayList());
        }
        return BusinessDTO.sucessBusiness(outDTO,"工作日志查询");
    }

    /**
     * 销售工作日志列表查询
     * @param indto
     * @return
     */
    private BusinessDTO<JobLogOutDTO> querySaleJobLog(JobLogInDTO indto){
        Integer totalRow = feedAllocMapper.querySaleJobLogListTotal(indto);
        totalRow = null == totalRow? 0:totalRow;
        JobLogOutDTO outDTO = new JobLogOutDTO();
        outDTO.settingPage(indto,totalRow);
        if(totalRow > 0){
            outDTO.setList(feedAllocMapper.querySaleJobLogList(indto));
        }
        outDTO.setJobLogTitle(JobLogUtils.saleLogTitle());
        if(ObjectUtils.isEmpty(outDTO.getList())){
            outDTO.setList(new ArrayList());
        }
        return BusinessDTO.sucessBusiness(outDTO,"销售工作日志查询");
    }

    /**
     * 饲料库存日志
     * @param indto
     * @return
     */
    private BusinessDTO<JobLogOutDTO> queryStockJobLog(JobLogInDTO indto){
        Integer type = 1;
        if(indto.isLogTypeStockZoo()){
            type = 2;
        }
        indto.setType(type);
        Integer totalRow = feedAllocMapper.queryStockJobLogListTotal(indto);
        totalRow = null == totalRow? 0:totalRow;
        JobLogOutDTO outDTO = new JobLogOutDTO();
        outDTO.settingPage(indto,totalRow);
        if(totalRow > 0){
            outDTO.setList(feedAllocMapper.queryStockJobLogList(indto));
        }
        outDTO.setJobLogTitle(JobLogUtils.stockLogTitle());
        if(ObjectUtils.isEmpty(outDTO.getList())){
            outDTO.setList(new ArrayList());
        }
        return BusinessDTO.sucessBusiness(outDTO,"饲料库存日志查询");
    }

    /**
     * 虾料配料信息查询
     * @param queryInDTO
     * @return
     */
    public PageOutDTO queryShrimpAllocInfo(FeedAllocQueryInDTO queryInDTO){
        queryInDTO.setCompanyId(AppSessionUtils.getCompanyId());
        queryInDTO.setAllocDate(AppUtils.todayYyyyMMdd());
        queryInDTO.checkParam();
        Integer totalRow = feedAllocMapper.queryShrimpAllocInfoTotal(queryInDTO);
        log.info("==========queryShrimpAllocInfo.totalRow={}",totalRow);
        totalRow = null == totalRow? 0:totalRow;

        PageOutDTO outDTO = new PageOutDTO();
        outDTO.settingPage(queryInDTO,totalRow);
        if(totalRow > 0){
            outDTO.setList(feedAllocMapper.queryShrimpAllocInfo(queryInDTO));
        }
        if(ObjectUtils.isEmpty(outDTO.getList())){
            outDTO.setList(new ArrayList());
        }
        return outDTO;
    }

    /**
     * 动保配料信息查询
     * @param queryInDTO
     * @return
     */
    public PageOutDTO<ZooWeighOutDTO> queryZooAllocInfo(FeedAllocQueryInDTO queryInDTO){
        queryInDTO.setCompanyId(AppSessionUtils.getCompanyId());
        queryInDTO.setAllocDate(AppUtils.todayYyyyMMdd());
        queryInDTO.checkParam();
        Integer totalRow = feedAllocMapper.queryZooAllocInfoTotal(queryInDTO);
        totalRow = null == totalRow? 0:totalRow;

        PageOutDTO<ZooWeighOutDTO> outDTO = new PageOutDTO();
        outDTO.settingPage(queryInDTO,totalRow);
        if(totalRow > 0){
            outDTO.setList(feedAllocMapper.queryZooAllocInfo(queryInDTO));
        }
        if(ObjectUtils.isEmpty(outDTO.getList())){
            outDTO.setList(new ArrayList());
        }
        return outDTO;
    }

    /**
     * 查询动保任务列表
     * @param taskGroupId
     * @return
     */
    public BusinessDTO<Object> queryZooTaskList(String taskGroupId){
        List<Map<String, Object>> zooTaskList = feedAllocMapper.queryZooTaskList(taskGroupId);
        if(ObjectUtils.isEmpty(zooTaskList)){
            zooTaskList = new ArrayList<>();
        }
        Map<String,Object> map = new HashMap<>();
        map.put("zooTaskList",zooTaskList);
        return BusinessDTO.sucessBusiness(map,"查询动保任务列表");
    }

    /**
     * 查询未喂料列表
     * @param companyId
     * @return
     */
    List<Map<String,Object>> queryUnfeedList(String companyId){
        return feedAllocMapper.queryUnfeedList(companyId);
    }
    public BusinessDTO<Object> queryUnfeedList(){
        List<Map<String,Object>> unfeedList = this.queryUnfeedList(AppSessionUtils.getCompanyId());
        if(ObjectUtils.isEmpty(unfeedList)){
            unfeedList = new ArrayList<>();
        }
        Map<String,Object> map = new HashMap<>();
        map.put("unfeedList",unfeedList);
        return BusinessDTO.sucessBusiness(map,"查询未喂料列表");
    }

    /**
     * 查询未喂料详情
     * @param companyId
     * @param allocDate
     * @param serialNo
     * @return
     */
    public List<Map<String,Object>> queryUnfeedDetail(String companyId,String allocDate,Integer serialNo){
        return feedAllocMapper.queryUnfeedDetail(companyId,allocDate,serialNo);
    }
    public BusinessDTO<Object> queryUnfeedDetail(String allocDate,Integer serialNo){
        List<Map<String,Object>> unfeedDetailList = this.queryUnfeedDetail(AppSessionUtils.getCompanyId(),allocDate,serialNo);
        if(ObjectUtils.isEmpty(unfeedDetailList)){
            unfeedDetailList = new ArrayList<>();
        }
        Map<String,Object> map = new HashMap<>();
        map.put("list",unfeedDetailList);
        return BusinessDTO.sucessBusiness(map,"查询未喂料详情");
    }

    /**
     * 取消未喂料任务
     * @param companyId
     * @param allocDate
     * @param serialNo
     */
    void cancelUnfeedTask(String companyId,String allocDate,Integer serialNo){
        feedAllocMapper.cancelUnfeedTask(companyId,allocDate,serialNo);
    }
    @Transactional
    public BusinessDTO<Object> cancelUnfeedTask(String allocDate,Integer serialNo){
        String companyId = AppSessionUtils.getCompanyId();
        if(StringUtils.isEmpty(companyId)){
            return BusinessDTO.failBusiness("用户未登陆或未分配公司");
        }
        List<DecrQtyDTO> qtyList = feedAllocMapper.queryUnfeedQty(companyId,allocDate,serialNo);
        Date date = AppUtils.parseYyyyMMdd(allocDate);
        List<QueryPondNamesOutDTO> pondNamesList = pondNamesService.queryUnfeededFeedPondNames(companyId,date,serialNo);
        this.cancelUnfeedTask(companyId,allocDate,serialNo);
        this.feedStock(AppSessionUtils.getUserId(),true,qtyList);
        messageService.sendCancelFeedListMessage(serialNo,date,pondNamesList);
        return BusinessDTO.sucessBusiness(new HashMap<>(),"取消未喂料任务");
    }


    /**
     * 检查库存
     * @param feedQtyList
     * @return
     */
      private List<FeedStockDTO> checkFeedStock(List<FeedQty> feedQtyList){
          return feedAllocMapper.checkFeedStock(feedQtyList);
      }

      private BusinessDTO<Object>  isFeedStock(List<FeedQty> feedQtyList){
          List<FeedStockDTO> stockDTOS = this.checkFeedStock(feedQtyList);
          if(ObjectUtils.isEmpty(stockDTOS)){
              return BusinessDTO.failBusiness("无库存");
          }
          for(FeedStockDTO stockDTO : stockDTOS){
              if( !stockDTO.isStockFull()){
                  return BusinessDTO.failBusiness(stockDTO.getBrand() + "[" + stockDTO.getName() + "]库存不足");
              }
          }
          return  BusinessDTO.sucessBusiness(null);
      }


    /**
     * 是否增加库存
     * @param isIncr
     * @param decrQtyDTOS
     */
    private void feedStock(String userId,boolean isIncr,List<DecrQtyDTO> decrQtyDTOS){
        feedStockService.feedStock(userId,isIncr,decrQtyDTOS);
    }

    private void feedStock(String userId,boolean isIncr,DecrQtyDTO decrQtyDTO){
        feedStockService.feedStock(userId,isIncr,decrQtyDTO);
    }

    private void feedStock(String userId, boolean isIncr, String feedId , Double qty){
        feedStockService.feedStock(userId,isIncr,feedId,qty);
    }

}
